#include "../ui/ui.h"
#define MQTT_BROKER_IP "8.134.212.245"
#define PUBLISH_PORT 1883
#define SUBSCRIBE_PORT 1884

// 发布者初始化
struct mosquitto * mqtt_publish_init(void)
{
    // 初始化MQTT库
    mosquitto_lib_init();

    // 2.创建一个客户端
    struct mosquitto * mosq = mosquitto_new(NULL, true, NULL);
    if(mosq == NULL) {
        perror("创建客户端失败\n");
        exit(-1);
    }

    // 3.连接服务器
    int ret = mosquitto_connect(mosq, MQTT_BROKER_IP, PUBLISH_PORT, 60);
    if(ret != MOSQ_ERR_SUCCESS) {
        perror("连接服务器失败\n");
        exit(-1);
    }

    // 4.启动网络线程
    mosquitto_loop_start(mosq);
    return mosq;
}

void sub_init(struct mosquitto * mosq)
{
    mqtt_sub(mosq, LED_TOPIC);
    mqtt_sub(mosq, LAMP_TOPIC);
    mqtt_sub(mosq, CURTAIN_TOPIC);
    mqtt_sub(mosq, WIND_TOPIC);
    mqtt_sub(mosq, LOCK_TOPIC);
    mqtt_sub(mosq, SENSOR_TOPIC_1);
    mqtt_sub(mosq, TV_TOPIC);
    mqtt_sub(mosq, AIRCOND_TOPIC_1);
    mqtt_sub(mosq, AIRCOND_TOPIC_2);
}
// 订阅者初始化
struct mosquitto * mqtt_subscribe_init(void)
{
    // 初始化MQTT库
    mosquitto_lib_init();

    // 2.创建一个客户端
    struct mosquitto * mosq = mosquitto_new(NULL, true, NULL);
    if(mosq == NULL) {
        perror("创建客户端失败\n");
        exit(-1);
    }

    // 3.连接服务器
    int ret = mosquitto_connect(mosq, MQTT_BROKER_IP, SUBSCRIBE_PORT, 60);
    if(ret != MOSQ_ERR_SUCCESS) {
        perror("连接服务器失败\n");
        exit(-1);
    }
    // 订阅主题
    sub_init(mosq);

    // 5.设置消息回调函数
    mosquitto_message_callback_set(mosq, on_message); // 设置接收消息回调函数
    // 6.循环接收消息 该函数会无线阻塞
    mosquitto_loop_forever(mosq, -1, 1); // 一直循环接收数据
    return mosq;
}

// 发布主题
int mqtt_pub(struct mosquitto * mosq, char * topic, char * payload, int payload_len)
{
    int ret = mosquitto_publish(mosq, NULL, topic, payload_len, payload, 0, false);
    if(ret != MOSQ_ERR_SUCCESS) {
        perror("发布消息失败\n");
        return -1;
    } else {
        printf("发布消息成功\n");
    }
    return ret;
}
// 订阅主题
int mqtt_sub(struct mosquitto * mosq, char * topic)
{
    int ret = mosquitto_subscribe(mosq, NULL, topic, 0);
    if(ret != MOSQ_ERR_SUCCESS) {
        perror("订阅失败\n");
        return -1;
    } else {
        printf("订阅主题%s成功\n", topic);
    }
    return ret;
}

void mqtt_destroy(struct mosquitto * mosq)
{
    mosquitto_destroy(mosq); // 销毁对象
    mosquitto_lib_cleanup(); // 清空函数库
}

// 订阅端处理函数
void on_message(struct mosquitto * mosq, void * obj, const struct mosquitto_message * msg)
{
    // 该处理函数在线程中执行 可能需要上锁操作
    /* This blindly prints the payload, but the payload can be anything so take care. */
    printf("%s %d %s\n", msg->topic, msg->qos, (char *)msg->payload);
    cJSON * json_obj = cJSON_Parse(msg->payload);
    cJSON * status   = cJSON_GetObjectItem(json_obj, "status");
    if(strcmp(msg->topic, LED_TOPIC) == 0) {
        // led
        SwitchControl(ui_LiveRoomLightSwitch, status->valuestring);
    } else if(strcmp(msg->topic, LAMP_TOPIC) == 0) {
        // 台灯
        cJSON * progress = cJSON_GetObjectItem(json_obj, "progress");
        if(strcmp(status->valuestring, "open") == 0)
            lv_slider_set_value(ui_LampSlider, progress->valueint, LV_ANIM_ON);
        else if(strcmp(status->valuestring, "close") == 0)
            lv_slider_set_value(ui_LampSlider, progress->valueint, LV_ANIM_OFF);
    } else if(strcmp(msg->topic, CURTAIN_TOPIC) == 0) {
        // 窗帘
        SwitchControl(ui_CurtainSwitch, status->valuestring);
    } else if(strcmp(msg->topic, WIND_TOPIC) == 0) {
        // 新风
        SwitchControl(ui_WindSwitch, status->valuestring);
    } else if(strcmp(msg->topic, LOCK_TOPIC) == 0) {
        // 锁
        SwitchControl(ui_LockSwitch, status->valuestring);
    } else if(strcmp(msg->topic, SENSOR_TOPIC_1) == 0) {
        // 传感器
        SwitchControl(ui_SensorSwitch, status->valuestring);
    } else if(strcmp(msg->topic, TV_TOPIC) == 0) {
        // 电视
        cJSON * voice = cJSON_GetObjectItem(json_obj, "voice");
        // 修改本地存储的值
        strcpy(tv.status, status->valuestring);
        tv.voice = voice->valueint;
        // 改变渲染状态
        if((strcmp(tv.status, "open") == 0) && tv.voice > 0 && tv.voice < 100) {
            // 将音量键改成橙色并中间显示音量
            lv_obj_set_style_text_color(ui_TVUpLabel, lv_color_hex(ORANGE), LV_PART_MAIN | LV_STATE_DEFAULT);
            lv_obj_set_style_text_color(ui_TVDownLabel, lv_color_hex(ORANGE), LV_PART_MAIN | LV_STATE_DEFAULT);
            char voicebuf[5] = {0};
            sprintf(voicebuf, "%d", tv.voice);
            lv_label_set_text(ui_TVChangeLabel, voicebuf);
        } else if(strcmp(tv.status, "close") == 0) {
            // 将音量键改成灰色并中间显示开机
            lv_obj_set_style_text_color(ui_TVUpLabel, lv_color_hex(GRAY), LV_PART_MAIN | LV_STATE_DEFAULT);
            lv_obj_set_style_text_color(ui_TVDownLabel, lv_color_hex(GRAY), LV_PART_MAIN | LV_STATE_DEFAULT);
            lv_label_set_text(ui_TVChangeLabel, LV_SYMBOL_POWER);
        }
    } else if(strcmp(msg->topic, AIRCOND_TOPIC_1) == 0) {
        // 空调1
        cJSON * temperature = cJSON_GetObjectItem(json_obj, "temperature");
        // 修改本地存储的值
        strcpy(airCond1.status, status->valuestring);
        airCond1.temperature = temperature->valueint;
        if((strcmp(airCond1.status, "open") == 0) && airCond1.temperature > 0 && airCond1.temperature < 100) {
            lv_obj_set_style_text_color(ui_AirConditionUpLabel1, lv_color_hex(ORANGE), LV_PART_MAIN | LV_STATE_DEFAULT);
            lv_obj_set_style_text_color(ui_AirConditionDownLabel1, lv_color_hex(ORANGE),
                                        LV_PART_MAIN | LV_STATE_DEFAULT);
            char buf[5] = {0};
            sprintf(buf, "%d", airCond1.temperature);
            lv_label_set_text(ui_AirConditionChangeLabel1, buf);
        } else if(strcmp(airCond1.status, "close") == 0) {
            lv_obj_set_style_text_color(ui_AirConditionUpLabel1, lv_color_hex(GRAY), LV_PART_MAIN | LV_STATE_DEFAULT);
            lv_obj_set_style_text_color(ui_AirConditionDownLabel1, lv_color_hex(GRAY), LV_PART_MAIN | LV_STATE_DEFAULT);
            lv_label_set_text(ui_AirConditionChangeLabel1, LV_SYMBOL_POWER);
        }
    } else if(strcmp(msg->topic, AIRCOND_TOPIC_2) == 0) {
        // 空调2
        cJSON * temperature = cJSON_GetObjectItem(json_obj, "temperature");
        // 修改本地存储的值
        strcpy(airCond2.status, status->valuestring);
        airCond2.temperature = temperature->valueint;
        if((strcmp(airCond2.status, "open") == 0) && airCond2.temperature > 0 && airCond2.temperature < 100) {
            lv_obj_set_style_text_color(ui_AirConditionUpLabel2, lv_color_hex(ORANGE), LV_PART_MAIN | LV_STATE_DEFAULT);
            lv_obj_set_style_text_color(ui_AirConditionDownLabel2, lv_color_hex(ORANGE),
                                        LV_PART_MAIN | LV_STATE_DEFAULT);
            char buf[5] = {0};
            sprintf(buf, "%d", airCond2.temperature);
            lv_label_set_text(ui_AirConditionChangeLabel1, buf);
        } else if(strcmp(airCond2.status, "close") == 0) {
            lv_obj_set_style_text_color(ui_AirConditionUpLabel2, lv_color_hex(GRAY), LV_PART_MAIN | LV_STATE_DEFAULT);
            lv_obj_set_style_text_color(ui_AirConditionDownLabel2, lv_color_hex(GRAY), LV_PART_MAIN | LV_STATE_DEFAULT);
            lv_label_set_text(ui_AirConditionChangeLabel2, LV_SYMBOL_POWER);
        }
    }
}
// 订阅者开关控制
void SwitchControl(lv_obj_t * obj, char * status)
{
    if(strcmp(status, "open") == 0)
        lv_obj_add_state(obj, LV_STATE_CHECKED);
    else if(strcmp(status, "close") == 0)
        lv_obj_remove_state(obj, LV_STATE_CHECKED);
}